package com.zhuoyue.web.controller;

import java.util.*;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zhuoyue.biz.core.api.domain.GatewayDO;
import com.zhuoyue.biz.core.api.dto.rep.InfraredDeviceButtonRepDTO;
import com.zhuoyue.biz.core.api.dto.rep.InfraredDeviceRepDTO;
import com.zhuoyue.biz.core.api.dto.req.InfraredDeviceDTO;
import com.zhuoyue.biz.core.api.service.GatewayService;
import com.zhuoyue.biz.core.api.service.InfraredDeviceService;
import com.zhuoyue.biz.core.api.service.impl.ProductInfoAppService;
import com.zhuoyue.common.aop.auth.CheckLogin;

import com.zhuoyue.common.aop.auth.User;
import com.zhuoyue.common.group.ValidationGroups;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.zhuoyue.biz.core.api.domain.InfraredDeviceButtonDO;
import com.zhuoyue.biz.core.api.domain.InfraredDeviceDO;
import com.zhuoyue.biz.core.api.service.InfraredDeviceButtonService;
import com.zhuoyue.common.constant.DeviceConstant;

import com.zhuoyue.common.dto.ControllerResult;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;


/**
 * @author wjming
 * @ClassName: AppInfraredDeviceController
 * @Description:红外设备添加，修改，删除，查询
 * @Date 2021/2/14 19:57
 */
@RestController
@Scope("prototype")
@RequestMapping("/api/infraredDevice")
@Validated
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AppInfraredDeviceController {

    private final InfraredDeviceService infraredDeviceService;
    private final InfraredDeviceButtonService infraredDeviceButtonService;
    private final GatewayService gatewayService;
    private final ProductInfoAppService productInfoAppService;

    /**
     * 获取家庭中的红外设备列表
     *
     * @return
     */
    @GetMapping("/list")
    @CheckLogin
    public ControllerResult getInfraredDeviceList(@NotBlank(message = "家庭ID不能为空！") String homeId, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [getInfraredDeviceList] -> [homeId:{}]", user.getAccount(), user.getOrgCode(), homeId);
        //根据homeId查询网关信息
        GatewayDO gatewayDO = gatewayService.getByHomeId(homeId);
        if (gatewayDO == null) {
            return ControllerResult.toParamFail("无网关信息");
        }
        List<InfraredDeviceRepDTO> result = infraredDeviceService.getInfraredDeviceListByGatewayId(gatewayDO);
        return ControllerResult.toReturnDataSuccess("查询成功", result);
    }


    @PostMapping("/add")
    @CheckLogin
    public ControllerResult addInfraredDevice(@Validated(ValidationGroups.Insert.class) @RequestBody InfraredDeviceDTO infDto, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [getInfraredDeviceList] -> [infraredDeviceDTO:{}]", user.getAccount(), user.getOrgCode(),
                JSONObject.toJSONString(infDto));

        if (DeviceConstant.DeviceType.CENTRAL_AC == infDto.getType()) {

            if (StringUtils.isEmpty(infDto.getCentralAcCode())) {
                return ControllerResult.toParamFail("中央空调编号不能为空！");
            }
        }
        InfraredDeviceDO infraredDevice = new InfraredDeviceDO();
        infraredDevice.setHomeId(infDto.getHomeId());
        infraredDevice.setDeviceId(infDto.getDeviceId());
        infraredDevice.setRoomId(infDto.getRoomId());
        infraredDevice.setName(infDto.getName());
        infraredDevice.setType(infDto.getType());
        infraredDevice.setImgUrl(infDto.getImgUrl());
        infraredDevice.setProdId(infDto.getProdId());
        if (StringUtils.isNotEmpty(infDto.getDeviceType())) {
            infraredDevice.setDeviceType(infDto.getDeviceType());
        } else {
            infraredDevice.setDeviceType(null);
        }

        if (DeviceConstant.DeviceType.CENTRAL_AC == infDto.getType()) {
            infraredDevice.setCentralAcCode("");
        } else {
            infraredDevice.setCentralAcCode(null);
        }

        infraredDevice.setActions(StringUtils.isEmpty(infDto.getActions()) || "{}".equals(infDto.getActions()) ? "" : infDto.getActions());

        InfraredDeviceDO result = infraredDeviceService.addInfraredDevice(infraredDevice);
        InfraredDeviceRepDTO infraredDeviceRepDTO = repDTO(result);
        log.info("result -> [getInfraredDeviceList] -> [InfraredDeviceRepDTO:{}]", user.getAccount(), user.getOrgCode(),
                JSONObject.toJSONString(infraredDeviceRepDTO));
        return ControllerResult.toReturnDataSuccess("添加成功", infraredDeviceRepDTO);
    }

    @PutMapping("/modify")
    @CheckLogin
    public ControllerResult updateInfraredDevice(@Validated(ValidationGroups.Update.class) InfraredDeviceDTO infDto) {
        InfraredDeviceDO infraredDevice = new InfraredDeviceDO();
        infraredDevice.setId(infDto.getId());
        infraredDevice.setRoomId(StringUtils.isNoneBlank(infDto.getRoomId()) ? infDto.getRoomId() : null);
        infraredDevice.setName(StringUtils.isNoneBlank(infDto.getName()) ? infDto.getName() : null);
        infraredDevice.setImgUrl(infDto.getImgUrl());
        infraredDevice.setProdId(infDto.getProdId());
        InfraredDeviceDO infraredDeviceDO = infraredDeviceService.updateInfraredDeviceById(infraredDevice);
        return ControllerResult.toReturnDataSuccess("修改成功", repDTO(infraredDeviceDO));
    }


    /**
     * 删除红外设备
     *
     * @param id 红外设备ID
     * @return
     */
    @DeleteMapping("/delete")
    @CheckLogin
    public ControllerResult deleteInfraredDevice(@RequestParam @NotBlank(message = "红外设备ID不能为空！") String id, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [getInfraredDeviceList] -> [infrared:{}]", user.getAccount(), user.getOrgCode(), id);
        infraredDeviceService.deleteInfraredDeviceById(id);
        return ControllerResult.toReturnMessageSuccess("设备删除成功");
    }


    //******************************************按钮列表***************************************************************


    @GetMapping("/button/list")
    @CheckLogin
    public ControllerResult getInfraredDeviceButtonList(@NotBlank(message = "红外设备ID不能为空！") String infraredDeviceId, HttpServletRequest request) {
        log.info("request ->  [getInfraredDeviceButtonList] -> [infraredDeviceId:{}]", infraredDeviceId);
        List<InfraredDeviceButtonDO> list = infraredDeviceButtonService.list(Wrappers.<InfraredDeviceButtonDO>lambdaQuery()
                .eq(InfraredDeviceButtonDO::getInfraredDeviceId, infraredDeviceId));
        List<InfraredDeviceButtonRepDTO> infraredDeviceButtonRepDtoS = new ArrayList<>();
        list.stream().forEach(buttonList -> {
            infraredDeviceButtonRepDtoS.add(repButtonDTO(buttonList));
        });
        log.info("result -> [getInfraredDeviceButtonList] -> [infraredDeviceButtonRepDTOS:{}]", list);
        return ControllerResult.toReturnDataSuccess("按钮列表获获取成功", infraredDeviceButtonRepDtoS);
    }


    //*******************************************新增红外按钮不包括小黑豆按钮******************************************

    /**
     * 新增红外设备按钮
     * 在每次按钮学习成功之后调用该接口
     *
     * @param deviceId         红外学习仪设备ID
     * @param infraredDeviceId 红外设备ID
     * @param name             按钮名称
     * @param orderNumber      按钮号
     * @return
     */
    @PostMapping("/button/add")
    @CheckLogin
    public ControllerResult addInfraredDeviceButton(String deviceId, @NotBlank(message = "红外设备ID不能为空！") String infraredDeviceId,
                                                    @NotBlank(message = "按钮名称不能为空！") String name,
                                                    @NotBlank(message = "按钮号不能为空") String orderNumber,
                                                    HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [addInfraredDeviceButton] -> [deviceId:{},infraredDeviceId:{},name:{},orderNumber:{}]",
                user.getAccount(), user.getOrgCode(), deviceId, infraredDeviceId, name, orderNumber);
        //判断红外设备的按钮是否已经存在
        InfraredDeviceButtonDO query = new InfraredDeviceButtonDO();
        query.setInfraredDeviceId(infraredDeviceId);
        query.setOrderNumber(orderNumber);
        List<InfraredDeviceButtonDO> buttonList = infraredDeviceButtonService.getButtonByQuery(query);

        if (CollectionUtils.isEmpty(buttonList)) {
            InfraredDeviceButtonDO button = new InfraredDeviceButtonDO();
            button.setInfraredDeviceId(infraredDeviceId);
            button.setName(name);
            button.setOrderNumber(orderNumber);
            InfraredDeviceButtonDO infraredDeviceButtonDO = infraredDeviceButtonService.addInfraredDeviceButton(button, deviceId);
            InfraredDeviceButtonRepDTO infraredDeviceButtonRepDTO = repButtonDTO(infraredDeviceButtonDO);
            log.info("result ->  [addInfraredDeviceButton] -> [{}]", infraredDeviceButtonRepDTO);
            return ControllerResult.toReturnDataSuccess("红外按钮添加成功", infraredDeviceButtonRepDTO);
        }
        return ControllerResult.toParamFail("按钮编号对应的功能已存在");
    }


    /**
     * 获取中央空调列表
     *
     * @param deviceId
     * @return
     */
    @GetMapping("/airDeviceList")
    @CheckLogin
    public ControllerResult listOfCentralAirConditioners(@RequestParam @NotBlank(message = "设备ID不能为空") String deviceId, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [ListOfCentralAirConditioners] -> [deviceId:{}]", user.getAccount(), user.getOrgCode(), deviceId);
        List<InfraredDeviceDO> result = infraredDeviceService.getAirDeviceListByDeviceId(deviceId);
        List<InfraredDeviceRepDTO> resultDTO = new ArrayList<>();
        result.stream().forEach(results -> {
            InfraredDeviceRepDTO infraredDeviceRepDTO = new InfraredDeviceRepDTO();
            BeanUtils.copyProperties(results, infraredDeviceRepDTO);
            resultDTO.add(infraredDeviceRepDTO);
        });
        log.info("result ->  [ListOfCentralAirConditioners] -> [resultDTO:{}]", resultDTO);
        return ControllerResult.toReturnDataSuccess("中央空调列表信息获取成功", resultDTO);
    }

    /**
     * 批量插入中央空调空调列表
     *
     * @param deviceId
     * @param caList
     * @return
     */
    @PostMapping("/addCADeviceList")
    @CheckLogin
    public ControllerResult addCaDeviceList(@NotBlank(message = "空调控制器id不能为空") String deviceId,
                                            @RequestParam(value = "CAList") @NotBlank(message = "中央空调数据不能为空") String caList,
                                            @NotBlank(message = "家庭ID不能为空") String homeId,
                                            HttpServletRequest request
    ) {
        User user = (User) request.getAttribute("user");
        log.info("request -> user:[{}_{}] [addCADeviceList] -> [deviceId:{},CAList:{},homeId:{}]", user.getAccount(), user.getOrgCode(), deviceId, caList, homeId);
        JSONArray objects = JSONArray.parseArray(caList);
        List<Map<String, Object>> caListByMap = new ArrayList<>(20);
        for (Object strList : objects) {
            Map<String, Object> parse = (Map<String, Object>) strList;
            caListByMap.add(parse);
        }

        for (int i = 0; i < caListByMap.size(); i++) {
            String centralAcCode = caListByMap.get(i).get("centralAcCode").toString();
            String name = caListByMap.get(i).get("name").toString();

            InfraredDeviceDO infraredDevice = new InfraredDeviceDO();
            infraredDevice.setDeviceId(deviceId);
            infraredDevice.setHomeId(homeId);
            infraredDevice.setCentralAcCode(centralAcCode);
            infraredDevice.setImgUrl("http://www.img.zyzncloud.com/zyzn/devices/ir/air.png");
            infraredDevice.setType(7);
            infraredDevice.setName(name);
            //插入数据库
            infraredDeviceService.addInfraredDevice(infraredDevice);
        }
        return ControllerResult.toReturnMessageSuccess("添加成功");
    }

    private InfraredDeviceRepDTO repDTO(InfraredDeviceDO infraredDeviceDO) {
        List<String> deviceFun = productInfoAppService.getDeviceFun(infraredDeviceDO.getProdId());
        InfraredDeviceRepDTO infraredDeviceRepDTO = new InfraredDeviceRepDTO().doToDto(infraredDeviceDO, deviceFun);
        return infraredDeviceRepDTO;
    }

    private InfraredDeviceButtonRepDTO repButtonDTO(InfraredDeviceButtonDO infraredDeviceButtonDO) {
        InfraredDeviceButtonRepDTO infraredDeviceRepDTO = new InfraredDeviceButtonRepDTO();
        BeanUtils.copyProperties(infraredDeviceButtonDO, infraredDeviceRepDTO);
        return infraredDeviceRepDTO;
    }


}
